 /*******************************************************************************
  * Copyright (c) 2006 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.update.internal.core;

 import java.io.IOException ;
 import java.io.InputStream ;
 import java.util.ArrayList ;

 import javax.xml.parsers.ParserConfigurationException ;
 import javax.xml.parsers.SAXParser ;
 import javax.xml.parsers.SAXParserFactory ;

 import org.eclipse.core.runtime.MultiStatus;
 import org.eclipse.update.core.model.FeatureModelFactory;
 import org.xml.sax.Attributes ;
 import org.xml.sax.InputSource ;
 import org.xml.sax.SAXException ;
 import org.xml.sax.SAXParseException ;
 import org.xml.sax.helpers.DefaultHandler ;

 public class DigestParser extends DefaultHandler {

     private InternalFeatureParser featureParser;
     
     private ArrayList featureModels;

     private SAXParser parser;

     private FeatureModelFactory factory;

     private String location;
     
     private final static SAXParserFactory parserFactory =
         SAXParserFactory.newInstance();
     
     public DigestParser() {
         super();
         featureParser = new InternalFeatureParser();
         try {
             parserFactory.setNamespaceAware(true);
             this.parser = parserFactory.newSAXParser();
         } catch (ParserConfigurationException e) {
             UpdateCore.log(e);
         } catch (SAXException e) {
             UpdateCore.log(e);
         }
     }

     public void init(FeatureModelFactory factory) {
         init(factory, null);
     }
     
     /**
      * @param factory
      * @param location
      * @since 3.1
      */
     public void init(FeatureModelFactory factory, String location) {
         
         this.factory = factory;
         this.location = location;
         factory = new LiteFeatureFactory();
         featureModels = new ArrayList ();
         featureParser.internalInit(factory, location);
     }

     /**
      * Parses the specified input steam and constructs a feature model.
      * The input stream is not closed as part of this operation.
      *
      * @param in input stream
      * @return feature model
      * @exception SAXException
      * @exception IOException
      * @since 2.0
      */
     public LiteFeature[] parse(InputStream in) throws SAXException , IOException {
         
         parser.parse(new InputSource (in), this);
         return (LiteFeature[])featureModels.toArray( new LiteFeature[featureModels.size()]);
     }


     /**
      * Returns all status objects accumulated by the parser.
      *
      * @return multi-status containing accumulated status, or <code>null</code>.
      * @since 2.0
      */
     public MultiStatus getStatus() {
         return featureParser.getStatus();
     }

     /**
      * Handle start of element tags
      * @see DefaultHandler#startElement(String, String, String, Attributes)
      * @since 2.0
      */
     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
         if(localName.equals("digest")) //$NON-NLS-1$
 return;
         if(localName.equals("feature")) //$NON-NLS-1$
 featureParser.internalInit(factory, location);
         
         featureParser.startElement(uri, localName, qName, attributes);
     }

     /**
      * Handle end of element tags
      * @see DefaultHandler#endElement(String, String, String)
      * @since 2.0
      */
     public void endElement(String uri, String localName, String qName) {
         if(localName.equals("digest")) //$NON-NLS-1$
 return;
         featureParser.endElement(uri, localName, qName);
         if(localName.equals("feature")) { //$NON-NLS-1$
 try {
                 featureModels.add(featureParser.getFeatureModel());
             } catch (SAXException e) {
                 e.printStackTrace();
             }
         }
     }
     

     /**
      * Handle character text
      * @see DefaultHandler#characters(char[], int, int)
      * @since 2.0
      */
     public void characters(char[] ch, int start, int length) {
         featureParser.characters(ch, start, length);
     }

     /**
      * Handle errors
      * @see DefaultHandler#error(SAXParseException)
      * @since 2.0
      */
     public void error(SAXParseException ex) {
         featureParser.error(ex);
     }

     /**
      * Handle fatal errors
      * @see DefaultHandler#fatalError(SAXParseException)
      * @exception SAXException
      * @since 2.0
      */
     public void fatalError(SAXParseException ex) throws SAXException {
         featureParser.fatalError(ex);
     }

     /**
      * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
      */
     public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
         featureParser.ignorableWhitespace(arg0, arg1, arg2);
     }
 }

